package com.tihi.xml;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import android.app.Activity;
import android.graphics.RectF;

import com.tihi.handsuiviewer.AppDef;
import com.tihi.treeview.UITreeHolder;
import com.tihi.treeview.UITreeHolder.UITreeData;
import com.unnamed.b.atv.model.TreeNode;

/**
 * UI xml 解析
 * 遍历节点，根节点、每个节点有子节点列表，递归只到结束
 * 
 * 展示位树形：一行textview：控件名（.后面最后一个） [][] bounds
 * 
 * @author duantihi
 *
 * @date 2016-1-30 下午4:01:58
 */
public class XmlTreeParser {
	
	private List<ViewNode> viewNodes;
	/** 链表方式保存所有tree的节点 */
	private List<TreeNode> treeNodes;
	/** xmlTree根节点 */
	private TreeNode rootTreeNode = TreeNode.root();
	private Activity mActivity;
	
	public XmlTreeParser(Activity activity) {
		mActivity = activity;
		viewNodes = new ArrayList<ViewNode>();
		treeNodes = new ArrayList<TreeNode>();
	}
	
	public TreeNode xmlParse() {
		try {
			Element root = getRoomElement();
			//uihirachy 只有一个跟node节点,  viewNode 与 treeNode 要一一对应上
			List<Element> subEles = root.elements(); //元素只会有一个
			if(subEles != null && subEles.size() == 1) {
				ViewNode rootNode = new ViewNode();
				//node 属性
				walkNodeAttr(subEles.get(0), rootNode); 
				
				TreeNode mRootNode = new TreeNode(new UITreeHolder.UITreeData(rootNode.getNodeDesc(), rootNode)).setViewHolder(new UITreeHolder(mActivity));;
				walkTree(subEles.get(0), rootNode, mRootNode);
				//递归遍历 xml，添加到rootNode
				rootTreeNode.addChildren(mRootNode);
			}
			
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rootTreeNode;
	}
	
	private void print() {
		if(viewNodes != null && viewNodes.size() > 0) {
			for(ViewNode node : viewNodes) {
				node.print();
			}
		}
	}
	
	/**
	 * 获取xml的根节点
	 * @return
	 * @throws DocumentException
	 */
	private Element getRoomElement() throws DocumentException {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File(AppDef.UIDUMP_XML_PATH));
		return document.getRootElement();
	}
	
	/**
	 * 递归遍历xml所有节点，并存入列表中
	 * @param node
	 */
	private void walkTree(Element node, ViewNode viewNode, TreeNode treeNode) {
		viewNodes.add(viewNode);
		treeNodes.add(treeNode);
		
		List subElements = node.elements();
		if(subElements == null || subElements.size() == 0) { //没有子节点
			viewNode.setSubNodes(null); 
		}else { //有子节点
			 for(Iterator it = subElements.iterator(); it.hasNext();) {
				 Element subEle = (Element) it.next();
				 ViewNode subViewNode = new ViewNode();
				 walkNodeAttr(subEle, subViewNode);
				 
				//针对 subNode 生成节点，挂到上一个
				TreeNode subTreeNode = new TreeNode(new UITreeHolder.UITreeData(subViewNode.getNodeDesc(), subViewNode)).setViewHolder(new UITreeHolder(mActivity));;
				walkTree(subEle, subViewNode, subTreeNode);
				
				treeNode.addChild(subTreeNode);
				viewNode.addSubNode(subViewNode);
			 }
		}
	}
	
	/**
	 * 节点的属性
	 */
	private void walkNodeAttr(Element node, ViewNode viewNode) {
		List<Attribute> attrList = node.attributes();
		for(Attribute attr : attrList) {
			viewNode.addAttr(attr.getName(), attr.getValue());
		}
	}
	
	//递归，传入一个节点，如果是element, 
	/**
	 * 根据点击x, y，从viewnodes中找到对应的node
	 * @param clickX
	 * @param clickY
	 * @return
	 */
	public ViewNode getViewNodeByClick(float clickX, float clickY) {
	    //根据 x,y 找到对应的 viewnode的 bounds，找到viewnode
		if(viewNodes == null) {
			return null;
		}
		ViewNode target = null;
		for(ViewNode curNode : viewNodes) {
			RectF curRectF = curNode.getBoundRectf();
			if(curRectF.contains(clickX, clickY)) {  //判断点是否在矩形框内
				if(target == null) {
					target = curNode;
				}else {  //判断当前的矩形框是否比之前的小
					RectF tmp = target.getBoundRectf();
					if(tmp.contains(curRectF)) {
						target = curNode;
					}
				}
			}
		}
		return target;
	}
	
	/**
	 * 根据 viewnode节点找到treeNode
	 * @param viewNode
	 * @return
	 */
	public TreeNode findTreeNodeByViewNode(ViewNode viewNode) {
		TreeNode treeNode = null;
		if(treeNodes != null) {
			for(TreeNode node : treeNodes) {
				UITreeData data = (UITreeData) node.getValue();
				if(data.getViewNode() == viewNode) {
					treeNode = node;
					break;
				}
			}
		}
		return treeNode;
	}
	
	public List<TreeNode> getTreeNodesList() {
		if(treeNodes != null) {
			for(TreeNode node : treeNodes) {
				((UITreeData) node.getValue()).getViewNode().print();
			}
		}
		return treeNodes;
	}

}
